// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: implementation of WaitWithMessageLoop.
//   $Id$


#include "stdafx.h"
#include "WaitWithMessageLoop.h"

DWORD xport::WaitWithMessageLoop(HANDLE hEvent,DWORD dwTimeout)
{
    DWORD dwRet;
    MSG msg;

    while(1)
    {
		dwRet = MsgWaitForMultipleObjects( 1,    // One event to wait for
				&hEvent,        // The array of events
				FALSE,          // Wait for 1 event
				dwTimeout,       // Timeout value
				QS_ALLINPUT);   // Any message wakes up
		if(dwRet == WAIT_OBJECT_0)
		{
			// The event was signaled, return
			return dwRet;
		} 
		else if(dwRet == WAIT_OBJECT_0 + 1)
		{
			// There is a window message available. Dispatch it.
			while(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE|PM_NOYIELD))
			{
				if(msg.message == WM_TIMER)
					break;
				else
				{
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
			}
		} 
		else
		{
			// Something else happened. Return.
			return dwRet;
		}
    }
	return dwRet;
}


typedef HRESULT(pOperationWithMessagePumpCallBack)(VOID **);

HRESULT xport::PerformOperationWithMessagePump(const UINT theMessage,pOperationWithMessagePumpCallBack * theCallBack ,VOID ** theArg)
{
	MSG msg;
	// force msg-q to be created just in case, NOP otherwise
	PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE| PM_NOYIELD);
	// msg to myself to do work
	DWORD dwThread = GetCurrentThreadId();
	HRESULT hr = E_FAIL;
//		LPARAM p = (LPARAM)this;
	LPARAM p = (LPARAM)0;
	PostThreadMessage(dwThread, theMessage, 0, p);
	// msg-pump

	while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD)) 
	{
		if(msg.message == WM_TIMER)
			break;

		if(msg.hwnd == NULL && msg.message == theMessage && msg.lParam == p)
		{
			hr = theCallBack(theArg);
			break;
		}
		else
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	return hr;
}